package cn.usian.jyzx.order.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.usian.common.exception.OrderException;
import cn.usian.jyzx.model.constant.Constant;
import cn.usian.jyzx.model.dto.OrderInfoDto;
import cn.usian.jyzx.model.entity.order.OrderInfo;
import cn.usian.jyzx.model.entity.order.OrderItem;
import cn.usian.jyzx.model.entity.order.OrderLog;
import cn.usian.jyzx.model.entity.product.ProductSku;
import cn.usian.jyzx.model.entity.user.UserAddress;
import cn.usian.jyzx.model.entity.user.UserInfo;
import cn.usian.jyzx.model.vo.common.ResultCodeEnum;
import cn.usian.jyzx.model.vo.h5.CartInfo;
import cn.usian.jyzx.model.vo.h5.OrderItemVo;
import cn.usian.jyzx.model.vo.h5.TradeVo;
import cn.usian.jyzx.order.fegin.CartFegin;
import cn.usian.jyzx.order.fegin.ProductFegin;
import cn.usian.jyzx.order.fegin.Userfegin;
import cn.usian.jyzx.order.mapper.OrderInfoMapper;
import cn.usian.jyzx.order.mapper.OrderItemMapper;
import cn.usian.jyzx.order.mapper.OrderLogMapper;
import cn.usian.jyzx.order.service.OrderService;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @TODO:
 * @Author:baimu
 * @Date:2024 11 07 14 34
 **/
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    RedisTemplate redisTemplate;


    public UserInfo getCurrentUserInfo(String token) {
        log.info("getCurrentUserInfo token:{}", token);
        String userInfoStr = (String) redisTemplate.opsForValue().get(Constant.LOGIN_TOKEN_KEY + token);
        log.info("userInfoStr:{}", userInfoStr);

        //json 字符串转成 UserInfo对象
        UserInfo userInfo = com.alibaba.fastjson2.JSON.parseObject(userInfoStr, UserInfo.class);


        return userInfo;
    }

    @Override
    public OrderInfo getOrderInfo(String orderNo) {
        OrderInfo orderInfo = orderInfoMapper.findOrderByOrderSn(orderNo);
        return orderInfo;
    }

    @Override
    public TradeVo trade(String token) {
        TradeVo tradeVo = new TradeVo();

        UserInfo userInfo = getCurrentUserInfo(token);

        Long id = userInfo.getId();
        //String
        List<Object> values = redisTemplate.opsForHash().values(Constant.CART_LIST_KEY + id);

//        List<CartInfo> cartInfoList = values.stream().map(item -> JSON.parseObject(item.toString(), CartInfo.class)).collect(Collectors.toList()).stream().map(cartInfo -> {
//            if (cartInfo.getIsChecked().intValue() == 1) {
//                return cartInfo;
//            } else {
//                return null;
//            }
//        }).collect(Collectors.toList());

        List<CartInfo> cartInfoList = values.stream().map(item -> JSON.parseObject(item.toString(), CartInfo.class)).collect(Collectors.toList());
        List<OrderItemVo> orderItemVoList = new ArrayList<OrderItemVo>();


        cartInfoList.forEach(cartInfo -> {
            if(cartInfo.getIsChecked().intValue()==1){
                OrderItemVo orderItemVo = new OrderItemVo();
                orderItemVo.setSkuPrice(cartInfo.getCartPrice());
                orderItemVo.setThumbImg(cartInfo.getImgUrl());
                orderItemVo.setSkuNum(cartInfo.getSkuNum());
                orderItemVo.setSkuName(cartInfo.getSkuName());
                orderItemVo.setSkuId(cartInfo.getSkuId());
                orderItemVoList.add(orderItemVo);
            }

        });
        tradeVo.setOrderItemList(orderItemVoList);




       // tradeVo.setTotalAmount(BigDecimal.ZERO);

        tradeVo.setTotalAmount(
                orderItemVoList.stream().map(
                        orderItemVo -> orderItemVo.getSkuPrice()
                                .multiply(new BigDecimal(orderItemVo.getSkuNum()))).
                        reduce(BigDecimal.ZERO, BigDecimal::add));


//        tradeVo.setOrderItemList(cartInfoList.stream().map(cartInfo -> {
//            log.info("cartInfo:{}", cartInfo);
//            if (cartInfo.getIsChecked().intValue() == 1) {
//                OrderItemVo orderItemVo = new OrderItemVo();
//                orderItemVo.setSkuPrice(cartInfo.getCartPrice());
//                orderItemVo.setThumbImg(cartInfo.getImgUrl());
//                orderItemVo.setSkuNum(cartInfo.getSkuNum());
//                orderItemVo.setSkuName(cartInfo.getSkuName());
//                orderItemVo.setSkuId(cartInfo.getSkuId());
//                return orderItemVo;
//            } else {
//                return null;
//            }
//
//        }).collect(Collectors.toList()));

        return tradeVo;
    }

    @Autowired
    ProductFegin productFegin;
    @Autowired
    Userfegin userfegin;

    @Autowired
    OrderInfoMapper orderInfoMapper;

    @Autowired
    OrderItemMapper orderItemMapper;


    @Autowired
    OrderLogMapper orderLogMapper;



    @Autowired
    CartFegin cartFegin;


    @Override
    @Transactional
    public String submitOrder(String token, OrderInfoDto orderInfoDto) {
        log.info("submitOrder orderInfoDto:{}", orderInfoDto);


        UserInfo userInfo = getCurrentUserInfo(token);

        Long userId = userInfo.getId();
        log.info("userId:{}", userId);

        //校验库存
        orderInfoDto.getOrderItemList().forEach(item->{
            Long skuId = item.getSkuId();
            log.info("skuId:{}", skuId);
            ProductSku productSku = productFegin.findById(skuId);
            //数据库的库存
            Integer stockNum = productSku.getStockNum();
            //购买的数量
            Integer skuNum = item.getSkuNum();

            if(skuNum.intValue()>stockNum.intValue()){
                log.info("库存不足，库存为：{},购买数量为：{}",stockNum,skuNum);
                throw new OrderException(ResultCodeEnum.INSUFFICIENT_INVENTORY);
            }

        });


        UserAddress userAddress = userfegin.findById(orderInfoDto.getUserAddressId());

        //参数1为终端ID
       //参数2为数据中心ID
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        //long orderNo = snowflake.nextId();
        String orderNo = snowflake.nextIdStr();
        log.info(" 订单号orderNo:{}", orderNo);


        //1: 构建OrderInfo 属性，保存到数据库
        OrderInfo orderInfo = new OrderInfo();
        //订单号,保证唯一
        orderInfo.setOrderNo(orderNo);
        //    @Schema(description = "订单状态【0->待付款；1->待发货；2->已发货；3->待用户收货，已完成；-1->已取消】")
        orderInfo.setOrderStatus(0);

        orderInfo.setFeightFee(orderInfoDto.getFeightFee());
        orderInfo.setUserId(userId);
        orderInfo.setNickName(userInfo.getUsername());

        orderInfo.setReceiverAddress(userAddress.getAddress());
        orderInfo.setReceiverCity(userAddress.getCityCode());
        orderInfo.setReceiverPhone(userAddress.getPhone());
        orderInfo.setReceiverProvince(userAddress.getProvinceCode());
        orderInfo.setReceiverDistrict(userAddress.getDistrictCode());
        orderInfo.setReceiverName(userAddress.getName());
        orderInfo.setCreateTime(new Date());
        orderInfo.setRemark(orderInfoDto.getRemark());
        orderInfo.setCouponAmount(BigDecimal.ZERO);

        BigDecimal totalAmount =
                orderInfoDto.getOrderItemList().stream().map(orderItemVo -> orderItemVo.getSkuPrice()
                        .multiply(new BigDecimal(orderItemVo.getSkuNum())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add);

        log.info("订单金额totalAmount:{}", totalAmount);



        orderInfo.setTotalAmount(totalAmount);
        orderInfo.setReceiverAddress(userAddress.getFullAddress());
        orderInfo.setOriginalTotalAmount(totalAmount.add(orderInfoDto.getFeightFee()));
        orderInfoMapper.save(orderInfo);


        log.info("orderInfo的生成的主键ID：{}",orderInfo.getId());






        //2: 构建OrderItem 属性，保存到数据库
        //OrderItem orderItem = new OrderItem();

        List<OrderItemVo> orderItemList = orderInfoDto.getOrderItemList();
//        List<OrderItem> orderItemList1 =new ArrayList<OrderItem>();
//        orderItemList.forEach(item->{
//            OrderItem orderItem = new OrderItem();
//            orderItem.setSkuId(item.getSkuId());
//            orderItem.setSkuName(item.getSkuName());
//            orderItem.setSkuNum(item.getSkuNum());
//            orderItem.setSkuPrice(item.getSkuPrice());
//            orderItem.setThumbImg(item.getThumbImg());
//            orderItem.setOrderId(Long.valueOf(orderNo));
//            orderItem.setCreateTime(new Date());
//            orderItem.setUpdateTime(new Date());
//            orderItem.setIsDeleted(1);
//            orderItemList1.add(orderItem);
//
//        });

        List<OrderItem> orderItemList1 = orderItemList.stream().map(item -> {
            OrderItem orderItem = new OrderItem();
            orderItem.setSkuId(item.getSkuId());
            orderItem.setSkuName(item.getSkuName());
            orderItem.setSkuNum(item.getSkuNum());
            orderItem.setSkuPrice(item.getSkuPrice());
            orderItem.setThumbImg(item.getThumbImg());
            orderItem.setOrderId(Long.valueOf(orderNo));
            orderItem.setCreateTime(new Date());
            orderItem.setUpdateTime(new Date());
            orderItem.setIsDeleted(1);
            return orderItem;
        }).collect(Collectors.toList());



        orderItemMapper.saveBatch(orderItemList1);


        //3: 构建OrderLog 属性，保存到数据库
        OrderLog orderLog = new OrderLog();
        orderLog.setNote("提交订单");
        orderLog.setProcessStatus(0);
        orderLog.setOperateUser(userInfo.getUsername());
        orderLog.setOrderId(Long.valueOf(orderNo));
        orderLogMapper.save(orderLog);

        cartFegin.getCartCheckedList(token);
        return String.valueOf(orderInfo.getId());
    }

    @Override
    public OrderInfo orderInfo(Long orderNo) {

        log.info("OrderInfo orderInfo(String orderNo):{}", orderNo);

        //OrderInfo orderInfo = orderInfoMapper.findOrderByOrderSn(orderNo);

        OrderInfo orderInfo =  orderInfoMapper.findOrderByOrderId(orderNo);
        Long orderInfoId = orderInfo.getId();

        List<OrderItem> orderItemList = orderItemMapper.findOrderItemByOrderId(orderInfoId);



        orderInfo.setOrderItemList(orderItemList);



        return orderInfo;
    }

    @Override
    public TradeVo buy(Long skuId, String token) {

        log.info("TradeVo buy(Long skuId:{}, String token:{})", skuId, token);


        UserInfo userInfo = getCurrentUserInfo(token);

        Long userId = userInfo.getId();
        log.info("userId:{}", userId);

        ProductSku productSku = productFegin.findById(skuId);

        TradeVo tradeVo = new TradeVo();


        List<OrderItemVo> list = new ArrayList<>();
        OrderItemVo orderItemVo = new OrderItemVo();
        orderItemVo.setSkuId(productSku.getId());
        orderItemVo.setSkuPrice(productSku.getSalePrice());
        orderItemVo.setSkuNum(1);
        orderItemVo.setSkuName(productSku.getSkuName());
        orderItemVo.setThumbImg(productSku.getThumbImg());

        list.add(orderItemVo);


        tradeVo.setOrderItemList(list);

        tradeVo.setTotalAmount(productSku.getSalePrice());


        return tradeVo;
    }

    @Override
    public PageInfo<OrderInfo> orderList(Integer pageNo, Integer pageSize, Integer orderStatus,String token ) {
        log.info("PageInfo<OrderInfo> orderList(Integer pageNo:{}, Integer pageSize:{}, Integer orderStatus:{})", pageNo, pageSize, orderStatus);




        UserInfo userInfo = getCurrentUserInfo(token);

        Long userId = userInfo.getId();
        log.info("userId:{}", userId);


        PageHelper.startPage(pageNo, pageSize);

        List<OrderInfo> orderInfoList = orderInfoMapper.findOrderByUserIdAndOrderSatus(userId, orderStatus);

        orderInfoList.forEach(orderInfo->{
            String orderNo = orderInfo.getOrderNo();

            List<OrderItem> orderItemList = orderItemMapper.findOrderItemByOrderId(Long.valueOf(orderNo));

            orderInfo.setOrderItemList(orderItemList);

        });



        return new PageInfo<OrderInfo>(orderInfoList);
    }

    @Override
    public int updateOrderStatus(String orderNo, Integer status) {
        return orderInfoMapper.updateOrderStatus(orderNo,status);

    }
}
